/**
 * 
 */
package org.vsg.stock.basic.service.volfigure.decrease;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import org.vsg.stock.basic.domain.VolFigureDetails;
import org.vsg.stock.basic.domain.VolFigureKlineDaily;
import org.vsg.stock.basic.domain.VolFigureKlineDailyPK;
import org.vsg.stock.basic.service.handler.VolFigureKlineDailyProcessor;
import org.vsg.stock.basic.service.volfigure.FigureCounter;
import org.vsg.stock.basic.service.volfigure.PriceReferenceLevel;
import org.vsg.stock.core.domain.StockDailyKLine;
import org.vsg.stock.core.indicator.kline.ZigIndicatorResultItem;

/**
 *  处理缩量柱模式2d0.参照量后，连续缩量三天,其中第一阴线, 第二或三天缩量
 *  
 *  分析结果：no records
 *  
 * @author Bill Vison
 *
 */
public class DecreaseM2a0aProcessor implements VolFigureKlineDailyProcessor {

	static private DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

	DecimalFormat nf = new DecimalFormat("##0.000");	
	
	private Set<String> dailyKeys = new HashSet<String>();	
	
	/* (non-Javadoc)
	 * @see org.vsg.stock.basic.service.handler.VolFigureKlineDailyProcessor#processDailyData(java.util.List)
	 */
	@Override
	public List<VolFigureKlineDaily> processDailyData(
			List<StockDailyKLine> stkDailyKLineList) {

		List<VolFigureKlineDaily> klineDailyList = new Vector<VolFigureKlineDaily>();		
		
		StockDailyKLine startLeveKline = null;

		for (int i = 0 ; i < stkDailyKLineList.size() ; i++) {

			boolean preCheckResult = preCheckFit(stkDailyKLineList , i );

			if (!preCheckResult) {
				continue;
			}
			startLeveKline = stkDailyKLineList.get(i);
			FigureCounter.countState(stkDailyKLineList, i);
			//System.out.println(startLeveKline.getId().getStockCode() + " , " + df.format( startLeveKline.getDate() ));

		}
		return klineDailyList;
	}

	// --- check the list is fit to char processor
	private boolean preCheckFit(List<StockDailyKLine> stkDailyKLineList , int index) {
		

		double maxPrice = 0;
		double maxVol = 0;
		double compareVol = 0;
		
		PriceReferenceLevel pricRefLevel = null;		
		
		StringBuffer hightStr = new StringBuffer("");
		StringBuffer midStr = new StringBuffer("");
		StringBuffer lowStr = new StringBuffer("");
		int[][] pricesArray = new int[3][3];			
		
		for (int i = 0 ; i < 4 ; i++) {
			if ( index + i >= stkDailyKLineList.size() ) {
				return false;
			}
			int currentIndex = index + i;

			// --- no need the first value
			if ( i == 0 ) {
				
				// --- 以第一条量柱为阳柱 ---
				StockDailyKLine curDailyKLine = stkDailyKLineList.get(currentIndex);
				
				if (curDailyKLine.getYieldRate() <= 0) {
					return false;
				}
				
				String valueStr = nf.format( (curDailyKLine.getOpen() + curDailyKLine.getClose() ) / 2 );
				maxPrice = Double.parseDouble( valueStr );
				maxVol = curDailyKLine.getVol();
				
				if (!( currentIndex-1 < 0 ) ) {
					pricRefLevel = new PriceReferenceLevel(curDailyKLine , stkDailyKLineList.get(currentIndex-1).getClose());
				}				
				continue;
			}
			
			double compareValue =  Math.abs( (double)stkDailyKLineList.get(currentIndex).getVol() - stkDailyKLineList.get(currentIndex-1).getVol());
			double compareRate = compareValue / stkDailyKLineList.get(currentIndex-1).getVol();
			
			// --- 两者相差不能太少 ---
			if ( compareRate < 0.05) {
				return false;
			}
			
			long currentDailyVol = stkDailyKLineList.get(currentIndex).getVol();
			long secondVol = stkDailyKLineList.get(currentIndex-1).getVol();
			
			if ( maxVol < currentDailyVol) {
				return false;
			}
			
			// --- second value not keep value ---
			if ( currentDailyVol > secondVol ) {
				return false;
			}
			
			if ( i == 1 || i== 2) {
				if ( stkDailyKLineList.get(currentIndex).getYieldRate() > 0) {
					return false;
				}				
			} else {
				if ( stkDailyKLineList.get(currentIndex).getYieldRate() < 0) {
					return false;
				}				
			}
			
			
			if ( i == 1 ) {

				// --- 不能出现缩倍柱 ---
				if ( currentDailyVol < maxVol * 0.55) {
					return false;
				}
				
			} else {

			}

			if ( pricRefLevel != null) {

				if ( hightStr.length() != 0) {
					hightStr.append(",");
				} 
				pricesArray[0][i-1] = pricRefLevel.checkLevelValue(stkDailyKLineList.get(currentIndex), StockDailyKLine.HIGH);
				hightStr.append( pricesArray[0][i-1] );

				if ( midStr.length() != 0) {
					midStr.append(",");
				} 
				pricesArray[1][i-1] = pricRefLevel.checkLevelValue(stkDailyKLineList.get(currentIndex), StockDailyKLine.MIDDLE);
				midStr.append(pricesArray[1][i-1] );
				
				if ( lowStr.length() != 0) {
					lowStr.append(",");
				} 
				pricesArray[2][i-1] = pricRefLevel.checkLevelValue(stkDailyKLineList.get(currentIndex), StockDailyKLine.LOW);

				lowStr.append( pricesArray[2][i-1] );
				
			}			
			
			
		}

		for (int j = 0 ; j < 3 ; j++) {

			if (pricesArray[1][j] < PriceReferenceLevel.MIDDLE_TO_CLOSE) {
				return false;
			}				
				
		}		
		
		return true;
	}
	
	private int handleInvoke(List<StockDailyKLine> stkDailyKLineList , int index) {
	
	
		return -1;
	}
	
	
	private List<ZigIndicatorResultItem> crests;

	/* (non-Javadoc)
	 * @see org.vsg.stock.basic.service.handler.VolFigureKlineDailyProcessor#setCrestsInCycle(java.util.List)
	 */
	@Override
	public void setCrestsInCycle(List<ZigIndicatorResultItem> crests) {
		this.crests = crests;

	}

	@Override
	public void setExistedVolFigureKineDaily(
			List<VolFigureKlineDaily> volFigureKlineDailyList) {
		// --- get the daily ---
		VolFigureKlineDailyPK id = null;
		for (VolFigureKlineDaily daily : volFigureKlineDailyList) {
			id = daily.getId();
			String keyLine = id.getStockCode()+ "," + id.getCodeVolFigureDetails()+"," + df.format( id.getStockStartDate() );
			dailyKeys.add( keyLine );
		}
		
	}

	private VolFigureDetails detail;	
	
	/* (non-Javadoc)
	 * @see org.vsg.stock.basic.service.handler.VolFigureKlineDailyProcessor#setCurrentVolFigureDetails(org.vsg.stock.basic.domain.VolFigureDetails)
	 */
	@Override
	public void setCurrentVolFigureDetails(VolFigureDetails detail) {
		this.detail = detail;

	}

	/* (non-Javadoc)
	 * @see org.vsg.stock.basic.service.handler.VolFigureKlineDailyProcessor#setTroughsInCycle(java.util.List)
	 */
	@Override
	public void setTroughsInCycle(List<ZigIndicatorResultItem> troughs) {
		// TODO Auto-generated method stub

	}

}
